/*
 * Copyright (c) 2011 Nokia Corporation.
 */

#include "levelmodel.h"

LevelModel::LevelModel(QObject *parent) :
    QAbstractListModel(parent)
{
    /***********************************************************************************************
    *Making the custom roles usable via qml.                                                      *
    ***********************************************************************************************/
    QHash<int, QByteArray> roles;
    roles[Qt::DisplayRole] = "display";
    roles[Qt::EditRole] = "edit";
    roles[LevelIdRole] = "level_id";
    roles[LevelNameRole] = "level_name";
    roles[LevelPriceRole] = "level_price";
    roles[LevelUnlockedRole] = "level_unlocked";
    roles[LevelShortDescriptionRole] = "level_short_desc";
    roles[LevelLongDescriptionRole] = "level_long_desc";
    roles[LevelType] = "level_type";
    setRoleNames(roles);
}

/***************************************************************************************************
*Standard Qt model view methods.                                                                   *
***************************************************************************************************/
int LevelModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return modelData.count();
}

QVariant LevelModel::data(const QModelIndex &index, int role) const
{
    QVariant result;
    if(index.row() < modelData.count() && index.row() >= 0){
        if(role == Qt::DisplayRole || role == Qt::EditRole || role == LevelNameRole)
            result = QVariant::fromValue(modelData.at(index.row()).name);
        else if(role == LevelIdRole)
            result = QVariant::fromValue(modelData.at(index.row()).id);
#if defined(IAP_ENABLED)
        else if(role == LevelPriceRole)
            result = QVariant::fromValue(modelData.at(index.row()).data.price);
#endif
        else if(role == LevelUnlockedRole)
            result = QVariant::fromValue(modelData.at(index.row()).unlocked);
#if defined(IAP_ENABLED)
        else if(role == LevelShortDescriptionRole)
            result = QVariant::fromValue(modelData.at(index.row()).data.shortDescription);
        else if(role == LevelLongDescriptionRole)
            result = QVariant::fromValue(modelData.at(index.row()).data.longDescription);
        else if(role == LevelType)
#endif
            result = QVariant::fromValue(modelData.at(index.row()).type);
    }
    return result;
}

bool LevelModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(index.row() < modelData.count() && index.row() >= 0){
        if(role == Qt::DisplayRole || role == Qt::EditRole || role == LevelNameRole
                && value.type() == QVariant::String)
            modelData[index.row()].name = value.toString();
        else if(role = LevelIdRole && value.type() == QVariant::String)
            modelData[index.row()].id = value.toString();
        else if(role == LevelUnlockedRole && value.type() == QVariant::Bool)
            modelData[index.row()].unlocked = value.toBool();
    }
    return false;
}

Qt::ItemFlags LevelModel::flags(const QModelIndex &index) const
{
    return QAbstractListModel::flags(index) | Qt::ItemIsEditable;
}

bool LevelModel::insertRows(int row, int count, const QModelIndex &parent)
{
    QAbstractListModel::beginInsertRows(parent,row,row + count - 1);
    for(int i = 0; i < count; ++i)
        modelData.insert(row + i,LevelData());
    QAbstractListModel::endInsertRows();
    return true;
}

bool LevelModel::removeRows(int row, int count, const QModelIndex &parent)
{
    if(row < modelData.count()){
        QAbstractListModel::beginRemoveRows(parent,row,row + count - 1);
        for(int i = 0; i < count; ++i)
            modelData.removeAt(row);
        QAbstractListModel::endRemoveRows();
        return true;
    }
    return false;
}
/**************************************************************************************************/

void LevelModel::setModelData(const QList<LevelData>& data)
{
    /***********************************************************************************************
    *Check the relative data set size and adjust accordingly(add/remove rows).                     *
    ***********************************************************************************************/
    int diff = modelData.count() - data.count();
    if(diff > 0)
        removeRows(modelData.count() - 1 - diff,diff);
    else if(diff < 0)
        insertRows(modelData.count(),-1 * diff);
    /***********************************************************************************************
    *Set the new model data and signalize that the entire model has changed.                       *
    ***********************************************************************************************/
    modelData = data;
    emit dataChanged(index(0),index(modelData.count() - 1));
}

void LevelModel::setLevelData(const LevelData& data)
{
    /***********************************************************************************************
    *Chceck if the model contains an item with the same id.                                        *
    ***********************************************************************************************/
    if(modelData.contains(data)){
        /*******************************************************************************************
        *Overite item witn new data.                                                               *
        *******************************************************************************************/
        int i = modelData.indexOf(data);
        modelData[i] = data;
        emit dataChanged(index(i),index(i));
    }else{
        /*******************************************************************************************
        *Insert a new item and set its data.                                                       *
        *******************************************************************************************/
        if(insertRows(modelData.count(),1)){
            int i = modelData.count() - 1;
            modelData[i] = data;
            emit dataChanged(index(i),index(i));
        }
    }
}

LevelData LevelModel::getById(QString itemId) const
{
    /***********************************************************************************************
    *Find and return the item with the given id.                                                   *
    ***********************************************************************************************/
    LevelData result;
    for(int i = 0; i < modelData.count(); ++i)
    {
        if(modelData.at(i).id == itemId){
            result = modelData.at(i);
            break;
        }
    }
    return result;
}
